package Generator;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class FixedDegreeGraph {

	private static final String NL = "\n";

	/**
	 * Entrance point for the program. java RandomGraph v, e, m, f
	 * 
	 * @param v
	 *            - the number of vertices
	 * @param e
	 *            - the number of edges leaving each node
	 * @param min
	 *            - the lower bound on the edge capacities
	 * @param max
	 *            - the upper bound on the edge capacities
	 * @param f
	 *            - path and file name for saving the graph
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		

		System.out.print("Enter the number of vertice in the graph\t");
		int v = GetInt();
		System.out.print("Enter the number of edge leaving each vertex\t");
		int e = GetInt();
		System.out.print("Enter the lower bound capacity\t");
		int min = GetInt();
		System.out.print("Enter the upper bound capacity\t");
		int max = GetInt();
//		System.out.print("Enter the file name\t");
		String fname = "v"+v+"-"+"e"+e+"-"+"low"+min+"-"+"upper"+max+".txt";
		String directory = System.getProperty("user.dir");
		FixedDegreeGraph randG = new FixedDegreeGraph();
		randG.toFile(FixedDegreeGraph.graphBuilder(v, e, min, max), fname);
		System.out.println("done");
	}

	/**
	 * This method creates a 3 token representation of a graph.
	 * 
	 * @param v
	 *            The number of vertices in the graph
	 * @param e
	 *            The number of edges leaving each vertice
	 * @param min
	 *            The lowerbound on the capacity value of each edge
	 * @param max
	 *            The upperbound on the capacity value of each edge
	 * @return A string buffer, each line contains 3 tokens corresponding to a
	 *         directed edge: the tail, the head, and the capacity.
	 */
	public static StringBuffer graphBuilder(int v, int e, int min, int max) {
		int i;
		int j;
		int head;
		int c;
		SortedSet s;
		Random gen = new Random();
		StringBuffer bfr = new StringBuffer();

		// System.out.println("1");
		// Add distinguished node s
		j = 1;
		s = new TreeSet();
		while (j <= e) {
			head = gen.nextInt(v) + 1;
			if (!s.contains(head)) {
				s.add(head);
				c = min + gen.nextInt(max - min + 1);
				bfr.append("s" + " " + "v" + head + " " + c + NL);
				j++;
			}
		}

		// System.out.println("2");

		// Add distinguished node t
		j = 1;
		s = new TreeSet();
		while (j <= e) {
			int tail = gen.nextInt(v) + 1;
			if (!s.contains(tail)) {
				s.add(tail);
				c = min + gen.nextInt(max - min + 1);
				bfr.append("v" + tail + " " + "t" + " " + c + NL);
				j++;
			}
		}

		// System.out.println("3");

		// Add internal nodes
		for (i = 1; i <= v; i++) {
			s = new TreeSet();
			s.add(i);
			j = 1;
			while (j <= e) {
				// System.out.println("into while");
				head = gen.nextInt(v) + 1;
				if (!s.contains(head)) {
					s.add(head);
					c = min + gen.nextInt(max - min + 1);
					bfr.append("v" + i + " " + "v" + head + " " + c + NL);
					j++;
				}
			}
		}
		// System.out.println("4");
		return bfr;
	}

	/**
	 * This method attempts to save a string at a given location.
	 * 
	 * @param outString
	 *            The StringBuffer containing the data being saved
	 * @param filename
	 *            The complete file path including file name
	 */
	private void toFile(StringBuffer outString, String filename) {
		try {
			BufferedWriter fout = new BufferedWriter(new FileWriter(filename));
			fout.write(outString.toString());
			fout.close();
		} catch (Exception e) {
			System.out.println("Error saving file.");
			System.out
					.println("Please check file paths and restart this program.");
			System.exit(1);
		}
	}

	public static String GetString() throws IOException {
		BufferedReader stringIn = new BufferedReader(new InputStreamReader(
				System.in));
		return stringIn.readLine();
	}

	public static int GetInt() throws IOException {
		String aux = GetString();
		return Integer.parseInt(aux);
	}

	public static double GetReal() throws IOException {
		String aux = GetString();
		Double d = new Double(aux);
		return d.doubleValue();
	}
}
